# coding: utf8


import os
import logging
import time
import re
import json
from lxml import etree
import traceback
import requests_html
from multiprocessing.pool import ThreadPool


"""哈尔滨工业大学（深圳）
电子与信息工程学院(56)

出错：接口调用错误。

服务器错误
"""

logging.basicConfig(level=logging.INFO)

session = requests_html.HTMLSession()
pool = ThreadPool(1)  # 要使用 hanlp, 线程数设为1


sex_ptn = re.compile(r'([男|女])')
degree_ptn = re.compile(r'学位[:： ]?(\S+)')
dep_ptn = re.compile(r'(?:所在单位|目前就职)[:： ]?(\S+)')
subj_ptn = re.compile(r'学科[:： ]?(\S+)')
homepage_ptn = re.compile(r'主页地址[:： ]?(\S+)')

addr_ptn = re.compile(r'(?:通信地址|通讯地址|办公地址|办公地点|地址|Address)[:： ]{1,3}(\S+)')
tel_ptn = re.compile(r'(?:办公电话|电话|Tel|tel)[:： ]+([0-9+\-,]+)')
email_ptn = re.compile(r'(?:电子邮箱|电子信箱|E-mail|Email|email|e-mail|邮箱地址|邮\s*箱)[:： ]+(\S+@[.\S]+)')
ri_ptn = re.compile(r'研究(?:方向|领域|重点)(?:为|包括)*[:：\n ]?([ \n\S]+?[。\n])')
pos_ptn = re.compile(r"(教授|副教授|助理教授|研究员|副研究员|博士导师|硕士导师|博士生研究生|硕士生导师|IEEE Fellow|IEEE\s*会员|博士|讲师|教师|高级工程师|工程师)")
edu_ptn = re.compile(r"(?:考入|攻读|进修|毕业于|学位|博士后|访问|工程师)")
split_ptn = re.compile(r'([;；。\n])')


def teacher_list():
    headers = {"Accept": "application/json",
               "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
               "Origin": "http://faculty.hitsz.edu.cn",
               "Referer": "http://faculty.hitsz.edu.cn/discipline-direction?id=2&browseName=%E6%95%99%E5%B8%88%E5%90%8D%E5%BD%95&browseEnName=TEACHERS&deptName=600001"}
    try:
        r = session.post("http://faculty.hitsz.edu.cn/sysBrowseShow/getUserInfoByDeptId.do", data='deptId=600001&id=2', headers=headers)
        if r.status_code == 200:
            lis = r.json()
            teachers = []

            logging.info("request msg: %s", lis['message'])

            for li in lis.get("list", []):
                user_id = li['id']
                name = li['userName']
                avatar = "http://faculty.hitsz.edu.cn/file/showHP.do?d=" + user_id
                url = li.get('url', None)
                url = "http://faculty.hitsz.edu.cn/" + url if url else ''

                logging.info("name: %s, url: %s", name, url)
                teachers.append((name, url))
            pool.imap_unordered(teacher_detail, teachers)
        else:
            logging.warning("wrong status code: %s", r.status_code)
            r.raise_for_status()
    except Exception as e:
        traceback.print_exc()
        raise e


def teacher_detail(payload):
    name, url = payload
    logging.info("loading %s ...", name)

    try:
        r = session.get(url)
        if r.status_code == 200:
            basic_info = r.html.xpath("//div[@id='teacher_info']")[0]

            avatar = basic_info.xpath("//div[contains(@class, 'part1 part')][1]//div[contains(@class, 'pic user-img')][1]/img[@class='img-thumbnail'][1]/@data-src")
            avatar = r.html.base_url + avatar[0] if avatar else ''

            nation = basic_info.xpath('//div[contains(@class, "part2 part")][1]//*[@class="user-country"]/text()')
            nation = "".join(nation) if nation else ''

            pos = basic_info.xpath('//div[contains(@class, "part3 part")][1]//*[contains(@class, "user-post")]/text()')
            pos = ", ".join(pos) if pos else ''

            other_info = basic_info.xpath("//div[contains(@class, 'part4 part')][1]")
            other_info = other_info[0].full_text if other_info else ''

            dep, subj, ri, homepage = [ptn.search(other_info) for ptn in (dep_ptn, subj_ptn, ri_ptn, homepage_ptn)]
            dep, subj, ri, homepage = [(match.group(1) if match else '') for match in (dep, subj, ri, homepage)]

            honors = r.html.xpath("//div[@id='teacher-honor-show']")
            honors = honors[0].full_text if honors else ''

            contact_info = r.html.xpath("//div[contains(@class, 'col-r')][1]")
            contact_info = contact_info[0].full_text if contact_info else ''

            tel, email, addr = [ptn.search(contact_info) for ptn in (tel_ptn, email_ptn, addr_ptn)]
            tel, email, addr = [(match.group(1) if match else '') for match in (tel, email, addr)]

            tid = r.html.xpath("//div[contains(@class, 'col-l teacher-body')][1]/@data-tid")
            tid = tid[0] if tid else None

            if not tid:
                logging.warning("%s tid req failed.", name)
                return

            api_url = "http://faculty.hitsz.edu.cn/TeacherHome/teacherBody.do"
            headers = {
                "Accept": "application/json, text/javascript, */*; q=0.01",
                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                "Host": "faculty.hitsz.edu.cn",
                "Origin": "http://faculty.hitsz.edu.cn",
                "Referer": url
            }

            data = "id=%s" % tid

            r1 = session.post(api_url, headers=headers, data=data)
            if r1.status_code != 200:
                logging.warning("%s body req failed.", name, r1.status_code)
                return

            nodes = etree.HTML(r1.text.replace('\\"', '"')).xpath(".//*[@id='myTabContent'][1]//*[contains(@class, 'lv1')]")
            content = []

            for node in nodes:
                header = node.xpath(".//div[contains(@class, 'lv1-header')][1]//*[contains(@class, 'lv1-title')][1]/text()")
                header = header[0] if header else ''

                cont = node.xpath(".//*[contains(@class, 'lv3 table')]//*/text()")
                cont = " ".join(cont) if cont else ''

                content.append("\n%s\n%s" % (header, cont))
            content = "\n".join(content)

            logging.info("name: %s, nation: %s, pos: %s, dep: %s, subj: %s, ri: %s, homepage: %s, tel: %s, email: %s, addr: %s, avatar: %s, content: %s",
                         name, nation, pos, dep, subj, ri, homepage, tel, email, addr, avatar, content)

            pass
        else:
            logging.warning("wrong status code: %s", r.status_code)
            r.raise_for_status()
    except Exception as e:
        traceback.print_exc()
        raise e


if __name__ == '__main__':
    teacher_list()

    pool.close()
    pool.join()

    session.close()

    pass



